home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 August / August CD.bin / Shareware / Programming / SpriteWorld / Sources / SpriteLayer.c < prev    next >
Text File  |  1994-04-25  |  9KB  |  354 lines

  1. ///--------------------------------------------------------------------------------------
  2. //    SpriteLayer.c
  3. //
  4. //    Created:    Tuesday, October, 1992 at 10:10:06 PM
  5. //    By:        Tony Myles
  6. //
  7. //    Copyright: © 1991-94 Tony Myles, All rights reserved worldwide
  8. //
  9. //    Description:    implementation of the sprite layers
  10. ///--------------------------------------------------------------------------------------
  11.  
  12.  
  13. #ifndef __SWCOMMON__
  14. #include "SWCommonHeaders.h"
  15. #endif
  16.  
  17. #ifndef __MEMORY__
  18. #include <Memory.h>
  19. #endif
  20.  
  21. #ifndef __SPRITEWORLDUTILS__
  22. #include "SpriteWorldUtils.h"
  23. #endif
  24.  
  25. #ifndef __SPRITEWORLD__
  26. #include "SpriteWorld.h"
  27. #endif
  28.  
  29. #ifndef __SPRITELAYER__
  30. #include "SpriteLayer.h"
  31. #endif
  32.  
  33. #ifndef __SPRITE__
  34. #include "Sprite.h"
  35. #endif
  36.  
  37. #if MPW
  38. #pragma segment SpriteWorld
  39. #endif
  40.  
  41.  
  42. ///--------------------------------------------------------------------------------------
  43. //    SWCreateSpriteLayer
  44. ///--------------------------------------------------------------------------------------
  45.  
  46. SW_FUNC OSErr SWCreateSpriteLayer(
  47.     SpriteLayerPtr *spriteLayerP)
  48. {
  49.     OSErr err;
  50.     SpriteLayerPtr tempSpriteLayerP;
  51.  
  52.     err = noErr;
  53.     *spriteLayerP = NULL;
  54.  
  55.     tempSpriteLayerP = (SpriteLayerPtr)NewPtrClear((Size)sizeof(SpriteLayerRec));
  56.  
  57.     if (tempSpriteLayerP != NULL)
  58.     {
  59.         *spriteLayerP = tempSpriteLayerP;
  60.     }
  61.     else
  62.     {
  63.         err = MemError();
  64.     }
  65.  
  66.     return err;
  67. }
  68.  
  69.  
  70. ///--------------------------------------------------------------------------------------
  71. //    SWDisposeSpriteLayer
  72. ///--------------------------------------------------------------------------------------
  73.  
  74. SW_FUNC void SWDisposeSpriteLayer(
  75.     SpriteLayerPtr spriteLayerP)
  76. {
  77.     if (spriteLayerP != NULL)
  78.     {
  79.         DisposePtr((Ptr)spriteLayerP);
  80.     }
  81. }
  82.  
  83.  
  84. ///--------------------------------------------------------------------------------------
  85. //    SWAddSprite
  86. ///--------------------------------------------------------------------------------------
  87.  
  88. SW_FUNC void SWAddSprite(
  89.     SpriteLayerPtr spriteLayerP,
  90.     SpritePtr newSpriteP)
  91. {
  92.     SpritePtr tailSpriteP = spriteLayerP->tailSpriteP;
  93.  
  94.     if (tailSpriteP != NULL)
  95.     {
  96.             // doubly link the new sprite
  97.         tailSpriteP->nextSpriteP = newSpriteP;
  98.         newSpriteP->prevSpriteP = tailSpriteP;
  99.         newSpriteP->nextSpriteP = NULL;
  100.     }    
  101.     else
  102.     {
  103.         newSpriteP->prevSpriteP = NULL;
  104.         newSpriteP->nextSpriteP = NULL;
  105.  
  106.             // make the new sprite the head
  107.         spriteLayerP->headSpriteP = newSpriteP;
  108.     }
  109.  
  110.         // make the new sprite the tail
  111.     spriteLayerP->tailSpriteP = newSpriteP;
  112. }
  113.  
  114.  
  115. ///--------------------------------------------------------------------------------------
  116. //    SWRemoveSprite
  117. ///--------------------------------------------------------------------------------------
  118.  
  119. SW_FUNC void SWRemoveSprite(
  120.     SpriteLayerPtr spriteLayerP,
  121.     SpritePtr oldSpriteP)
  122. {
  123.         // is this not the tail sprite?
  124.     if (oldSpriteP->nextSpriteP != NULL)
  125.     {
  126.             // link the next sprite to the prev sprite
  127.         oldSpriteP->nextSpriteP->prevSpriteP = oldSpriteP->prevSpriteP;
  128.     }
  129.     else
  130.     {
  131.             // make the prev sprite the tail
  132.         spriteLayerP->tailSpriteP = oldSpriteP->prevSpriteP;
  133.     }
  134.  
  135.         // is this not the head sprite?
  136.     if (oldSpriteP->prevSpriteP != NULL)
  137.     {
  138.             // link the prev sprite to the next sprite
  139.         oldSpriteP->prevSpriteP->nextSpriteP = oldSpriteP->nextSpriteP;
  140.     }
  141.     else
  142.     {
  143.             // make the next sprite the first sprite
  144.         spriteLayerP->headSpriteP = oldSpriteP->nextSpriteP;
  145.     }
  146.  
  147.     oldSpriteP->prevSpriteP = NULL;
  148.     oldSpriteP->nextSpriteP = NULL;
  149. }
  150.  
  151.  
  152. ///--------------------------------------------------------------------------------------
  153. //    SWRemoveAllSpritesFromLayer
  154. ///--------------------------------------------------------------------------------------
  155.  
  156. SW_FUNC void SWRemoveAllSpritesFromLayer(
  157.     SpriteLayerPtr srcSpriteLayerP)
  158. {
  159.     SpritePtr curSpriteP;
  160.  
  161.     while ((curSpriteP = SWGetNextSprite(srcSpriteLayerP, NULL)) != NULL)
  162.     {
  163.         SWRemoveSprite(srcSpriteLayerP, curSpriteP);
  164.     }
  165. }
  166.  
  167.  
  168. ///--------------------------------------------------------------------------------------
  169. //    SWSwapSprite
  170. ///--------------------------------------------------------------------------------------
  171.  
  172. SW_FUNC void SWSwapSprite(
  173.     SpriteLayerPtr spriteLayerP,
  174.     SpritePtr srcSpriteP,
  175.     SpritePtr dstSpriteP)
  176. {
  177.     register SpritePtr swapSpriteP;
  178.     
  179.     swapSpriteP = srcSpriteP->nextSpriteP;
  180.     srcSpriteP->nextSpriteP = dstSpriteP->nextSpriteP;
  181.     dstSpriteP->nextSpriteP = swapSpriteP;
  182.  
  183.     swapSpriteP = srcSpriteP->prevSpriteP;
  184.     srcSpriteP->prevSpriteP = dstSpriteP->prevSpriteP;
  185.     dstSpriteP->prevSpriteP = swapSpriteP;
  186.  
  187.     if (srcSpriteP->nextSpriteP == NULL)
  188.     {
  189.         spriteLayerP->tailSpriteP = srcSpriteP;
  190.     }
  191.     else if (srcSpriteP->prevSpriteP == NULL)
  192.     {
  193.         spriteLayerP->headSpriteP = srcSpriteP;
  194.     }
  195.  
  196.     if (dstSpriteP->nextSpriteP == NULL)
  197.     {
  198.         spriteLayerP->tailSpriteP = dstSpriteP;
  199.     }
  200.     else if (dstSpriteP->prevSpriteP == NULL)
  201.     {
  202.         spriteLayerP->headSpriteP = dstSpriteP;
  203.     }
  204. }
  205.  
  206.  
  207. ///--------------------------------------------------------------------------------------
  208. //    SWGetNextSprite
  209. ///--------------------------------------------------------------------------------------
  210.  
  211. SW_FUNC SpritePtr SWGetNextSprite(
  212.     SpriteLayerPtr spriteLayerP,
  213.     SpritePtr curSpriteP)
  214. {
  215.     return (curSpriteP == NULL) ? spriteLayerP->headSpriteP : curSpriteP->nextSpriteP;
  216. }
  217.  
  218.  
  219. ///--------------------------------------------------------------------------------------
  220. //    SWLockSpriteLayer
  221. ///--------------------------------------------------------------------------------------
  222.  
  223. SW_FUNC void SWLockSpriteLayer(
  224.     SpriteLayerPtr spriteLayerP)
  225. {
  226.     SpritePtr curSpriteP;
  227.  
  228.     curSpriteP = spriteLayerP->headSpriteP;
  229.  
  230.     while (curSpriteP != NULL)
  231.     {
  232.         SWLockSprite(curSpriteP);
  233.  
  234.         curSpriteP = curSpriteP->nextSpriteP;
  235.     }
  236. }
  237.  
  238.  
  239. ///--------------------------------------------------------------------------------------
  240. //    SWUnlockSpriteLayer
  241. ///--------------------------------------------------------------------------------------
  242.  
  243. SW_FUNC void SWUnlockSpriteLayer(
  244.     SpriteLayerPtr spriteLayerP)
  245. {
  246.     SpritePtr curSpriteP;
  247.  
  248.     curSpriteP = spriteLayerP->headSpriteP;
  249.  
  250.     while (curSpriteP != NULL)
  251.     {
  252.         SWUnlockSprite(curSpriteP);
  253.  
  254.         curSpriteP = curSpriteP->nextSpriteP;
  255.     }
  256. }
  257.  
  258.  
  259. ///--------------------------------------------------------------------------------------
  260. //    SWCollideSpriteLayer
  261. ///--------------------------------------------------------------------------------------
  262.  
  263. SW_FUNC void SWCollideSpriteLayer(
  264.     SpriteLayerPtr srcSpriteLayerP,
  265.     SpriteLayerPtr dstSpriteLayerP)
  266. {
  267.     SpritePtr srcSpriteP;
  268.     SpritePtr dstSpriteP;
  269.     SpritePtr nextSrcSpriteP;
  270.     SpritePtr nextDstSpriteP;
  271.     Rect sectRect;
  272.  
  273.     srcSpriteP = srcSpriteLayerP->headSpriteP;
  274.  
  275.     while (srcSpriteP != NULL)
  276.     {
  277.         nextSrcSpriteP = srcSpriteP->nextSpriteP;
  278.         dstSpriteP = dstSpriteLayerP->headSpriteP;
  279.  
  280.         while (dstSpriteP != NULL)
  281.         {
  282.             nextDstSpriteP = dstSpriteP->nextSpriteP;
  283.  
  284.             if (srcSpriteP != dstSpriteP)
  285.             {
  286.                     // are the sprite’s rectangles overlapping?
  287.                 if ((srcSpriteP->destFrameRect.top < dstSpriteP->destFrameRect.bottom) &&
  288.                     (srcSpriteP->destFrameRect.bottom > dstSpriteP->destFrameRect.top) &&
  289.                     (srcSpriteP->destFrameRect.left < dstSpriteP->destFrameRect.right) &&
  290.                     (srcSpriteP->destFrameRect.right > dstSpriteP->destFrameRect.left))
  291.                 {
  292.                         // call the source sprite’s collision routine
  293.                     if (srcSpriteP->spriteCollideProc != NULL)
  294.                     {
  295.                         sectRect.left =
  296.                             SW_MAX(srcSpriteP->destFrameRect.left, dstSpriteP->destFrameRect.left);
  297.                         sectRect.top =
  298.                             SW_MAX(srcSpriteP->destFrameRect.top, dstSpriteP->destFrameRect.top);
  299.                         sectRect.right =
  300.                             SW_MIN(srcSpriteP->destFrameRect.right, dstSpriteP->destFrameRect.right);
  301.                         sectRect.bottom =
  302.                             SW_MIN(srcSpriteP->destFrameRect.bottom, dstSpriteP->destFrameRect.bottom);
  303.  
  304.                         (*srcSpriteP->spriteCollideProc)(srcSpriteP, dstSpriteP, §Rect);
  305.                     }
  306.                 }
  307.             }
  308.  
  309.             if (nextDstSpriteP != NULL)
  310.             {
  311.                 dstSpriteP = nextDstSpriteP;
  312.             }
  313.             else
  314.             {
  315.                 dstSpriteP = dstSpriteP->nextSpriteP;
  316.             }
  317.         }
  318.  
  319.         if (nextSrcSpriteP != NULL)
  320.         {
  321.             srcSpriteP = nextSrcSpriteP;
  322.         }
  323.         else
  324.         {
  325.             srcSpriteP = srcSpriteP->nextSpriteP;
  326.         }
  327.     }
  328. }
  329.  
  330.  
  331. ///--------------------------------------------------------------------------------------
  332. //    SWFindSpriteByPoint
  333. ///--------------------------------------------------------------------------------------
  334.  
  335. SpritePtr SWFindSpriteByPoint(
  336.     SpriteLayerPtr spriteLayerP,
  337.     SpritePtr startSpriteP,
  338.     Point testPoint)
  339. {
  340.     SpritePtr curSpriteP;
  341.  
  342.     curSpriteP = (startSpriteP == NULL) ? spriteLayerP->tailSpriteP : startSpriteP;
  343.  
  344.         // note that we traverse the sprites in reverse order
  345.         // since this will make the most sense if we are
  346.         // looking for a sprite that was clicked
  347.     while ((curSpriteP != NULL) && !SWIsPointInSprite(curSpriteP, testPoint))
  348.     {
  349.         curSpriteP = curSpriteP->prevSpriteP;
  350.     }
  351.  
  352.     return curSpriteP;
  353. }
  354.